
package jgf.lists;

import java.util.ArrayList;
import java.util.List;
import jgf.Arc;
import jgf.IGraph;
import jgf.exceptions.arc.ArcException;
import jgf.exceptions.arc.DuplicatedArcException;
import jgf.exceptions.node.DuplicatedNodeException;
import jgf.exceptions.node.UnexistentNodeException;

/**
 * 
 * @author Marcos Garcia Ortega <a href="mailto:thiamath@gmail.com">&lt;thiamath@gmail.com&gt;</a>
 */
public class Digraph extends GenericGraph{

	{type = IGraph.DIGRAPH;}

	/**
	 * Constructor that makes a simple and directed graph.
	 * @param id The ID number for the graph.
	 */
	public Digraph(Integer id) {
		super(id);
	}

	/**
	 * Constructor that makes a simple and directed graph with a label.
	 * @param id The ID number for the graph.
	 * @param label The label for the graph.
	 */
	public Digraph(Integer id, String label) {
		super(id, label);
	}

	public Digraph() {
		super();
	}

	@Override
	public List<Integer> getBackwardStar(Integer nodeId) {
		List<Integer> ret = new ArrayList<Integer>();
		for (Integer key : arcTree.keySet()) {
			if(arcTree.get(key).getTo().getId().equals(nodeId))
				ret.add(key);
		}
		return ret;
	}

	@Override
	public List<Integer> getForwardStar(Integer nodeId) {
		List<Integer> ret = new ArrayList<Integer>();
		for (Integer key : arcTree.keySet()) {
			if(arcTree.get(key).getFrom().getId().equals(nodeId))
				ret.add(key);
		}
		return ret;
	}

	@Override
	public Integer insertArc(Integer from, Integer to, String label)
			throws ArcException,
			DuplicatedArcException,
			DuplicatedNodeException,
			UnexistentNodeException {
		if(from == null || to == null){
			throw new ArcException(this.getClass(),
					"insertArc",
					new String[]{"from = " + from,
					"to = " + to,
					"label = " + label});//throw a DuplicatedArcException
		}
		if(from.equals(to))//If the 'from' and 'to' nodes are the same
			throw new DuplicatedNodeException(this.getClass(),
					"insertArc",
					new String[]{"from = " + from,
					"to = " + to,
					"label = " + label});//throw a DuplicatedNodeException
		for (Integer key : arcTree.keySet()) {//For each arc in the graph
			if(arcTree.get(key).getFrom().getId().equals(from)
					&& arcTree.get(key).getTo().getId().equals(to))//If have the same 'from' and 'to' nodes
				throw new DuplicatedArcException(this.getClass(),
					"insertArc",
					new String[]{"from = " + from,
					"to = " + to,
					"label = " + label});//throw a DuplicatedArcException
		}
		if(!nodeTree.containsKey(from)||
				!nodeTree.containsKey(to))//If the node 'from' or 'to' do not exist in the graph
			throw new UnexistentNodeException(this.getClass(),
					"insertArc",
					new String[]{"from = " + from,
					"to = " + to,
					"label = " + label});//throw a UnexistentNodeException
		Arc newArc = new Arc(this.arcIdCounter,
				nodeTree.get(from),
				nodeTree.get(to),
				label,
				this.getDefaultArcAttributes());//Creates the new Arc
		arcTree.put(arcIdCounter, newArc);//Put the new arc into the graph
		return arcIdCounter++;//Increment the ID number for the arcs
	}
}
